package top.someapp.dxf2dsvg.cad;

import com.aspose.cad.ImageOptionsBase;
import com.aspose.cad.Size;
import com.aspose.cad.fileformats.cad.CadImage;
import com.aspose.cad.fileformats.cad.CadLayoutDictionary;
import com.aspose.cad.fileformats.cad.cadobjects.CadBaseEntity;
import com.aspose.cad.fileformats.cad.cadobjects.CadBlockEntity;
import com.aspose.cad.fileformats.cad.cadobjects.CadLayout;
import com.aspose.cad.fileformats.cad.cadtables.CadBlockTableObject;
import com.aspose.cad.system.collections.Generic.Dictionary;
import com.aspose.cad.system.collections.Generic.KeyValuePair;

import javax.annotation.Nonnull;
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zwz
 * Created on 2020-04-22
 */
public class AutoCadImage {
    private final String fileName;
    private final String format;
    private final CadImage cadImage;
    private final List<String> layerNames;
    private final List<BlockTable> blockTables;
    private final Map<String, BlockEntity> blockEntityMap;
    private Map<String, CadLayout> layoutMap;
    private CadBaseEntity[] entities;

    AutoCadImage(@Nonnull File cadFile, @Nonnull CadImage image) {
        this.fileName = cadFile.getName();
        this.format = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
        this.cadImage = image;
        this.layerNames = new ArrayList<>();
        this.blockTables = new ArrayList<>();
        this.blockEntityMap = new LinkedHashMap<>();
    }

    public String getFileName() {
        return fileName;
    }

    public String getSimpleFileName() {
        int index = fileName.lastIndexOf('.');
        return index > 0 ? fileName.substring(0, index) : fileName;
    }

    public String getFormat() {
        return format;
    }

    public Size getSize() {
        return cadImage.getSize();
    }

    public Map<String, CadLayout> getLayoutMap() {
        if (layoutMap == null) {
            layoutMap = new LinkedHashMap<>();
            CadLayoutDictionary layouts = cadImage.getLayouts();
            for (CadLayout layout : layouts.getValues()) {
                layoutMap.put(layout.getLayoutName(), layout);
            }
        }
        return layoutMap;
    }

    public List<String> getLayerNames() {
        if (layerNames.isEmpty()) {
            layerNames.addAll(cadImage.getLayers().getLayersNames());
        }
        return layerNames;
    }

    public List<BlockTable> getBlocksTables() {
        if (blockTables.isEmpty()) {
            for (Object item : cadImage.getBlocksTables()) {
                blockTables.add(new BlockTable((CadBlockTableObject) item));
            }
        }
        return blockTables;
    }

    public Map<String, BlockEntity> getBlockEntityMap() {
        if (blockEntityMap.isEmpty()) {
            for (Dictionary.Enumerator<String, CadBlockEntity> it = cadImage.getBlockEntities().iterator();
                 it.hasNext(); ) {
                KeyValuePair<String, CadBlockEntity> next = it.next();
                blockEntityMap.put(next.getKey(), new BlockEntity(next.getValue()));
            }
        }
        return blockEntityMap;
    }

    public CadBaseEntity[] getEntities() {
        if (entities == null) {
            entities = cadImage.getEntities();
        }
        return entities;
    }

    public void writeTo(@Nonnull OutputStream out, @Nonnull ImageOptionsBase options) {
        cadImage.save(out, options);
    }

    @Override
    public String toString() {
        return "AutoCadImage{" +
                "fileName='" + fileName + '\'' +
                ", format='" + format + '\'' +
                ",\nlayerNames=" + layerNames +
                ",\nblockEntityMap.size=" + blockEntityMap.size() +
                ",\nentities.length=" + getEntities().length +
                '}';
    }
}
